package com.shxy.api.controller;

import com.alibaba.fastjson.JSONObject;
import com.shxy.api.bean.news.CatalogBean;
import com.shxy.api.bean.news.NewsBean;
import com.shxy.api.bean.news.NewsInfo;
import com.shxy.api.common.ApiResult;
import com.shxy.api.common.ResultCode;
import com.shxy.api.controller.ui.NewsAdd;
import com.shxy.api.service.ILoginService;
import com.shxy.api.service.INewsService;
import lombok.extern.java.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.validation.Errors;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 新闻管理控制器
 */
@RestController
@RequestMapping("/v1/news")
@Log
@Validated
public class NewsController {
    @Autowired private INewsService newsService;
    @Autowired private ILoginService loginService;

    /**
     * 添加新闻
     * @param news 内容
     * @return
     */
    @PostMapping("/add")
    public ApiResult addNews(@RequestBody @Valid NewsAdd news) {
        // 1、检查用户和栏目是否存在
        if(!newsService.isCatalogExist(news.getCatalogId()) || !loginService.isUserExist(news.getAuthorId())) {
            return ApiResult.create(ResultCode.PARAM_NOT_VALID);
        }

        // 2、检查该栏目下是否存在相同的标题
        if(newsService.isNewsExists(news.getTitle(), news.getCatalogId())) {
            return ApiResult.create(ResultCode.NEWS_EXISTS);
        }

        // 3、保存新闻内容
        NewsInfo newsInfo = newsService.saveNews(news.getTitle(), news.getContent(), news.getCatalogId(), news.getAuthorId());
        // 4、返回新闻编号
        return ApiResult.create(newsInfo.getId());
    }

    /**
     * 修改新闻内容
     * @param id 编号
     * @param title 标题
     * @param content 内容
     * @return
     */
    @PostMapping("/edit/id/{id}")
    public ApiResult editNews(@PathVariable String id,
                              @RequestParam @NotBlank(message = "标题不能为空") String title,
                              @RequestParam @NotBlank(message = "内容不能为空") String content) {
        // 1、根据编号查询新闻
        NewsInfo newsInfo = newsService.getNewsInfoById(id);
        // 2、如果新闻不存在
        if(newsInfo == null) {
            return ApiResult.create(ResultCode.PARAM_NOT_VALID);
        }

        // 3、修改标题和内容
        NewsBean news = newsInfo.getNews();
        news.setTitle(title);
        news.setContent(content);
        // 4、保存修改
        if(newsService.updateNews(news)) {
            return ApiResult.success();
        }
        return ApiResult.fail();
    }

    /**
     * 根据编号查询新闻详情
     * @param id 编号
     * @return
     */
    @GetMapping("/get/id/{id}")
    public ApiResult getById(@PathVariable(name = "id") String id) {
        NewsInfo newsInfo = newsService.getNewsInfoById(id);
        if(newsInfo == null) {
            return ApiResult.create(ResultCode.PARAM_NOT_VALID);
        }

        JSONObject jo = new JSONObject();
        jo.put("id", newsInfo.getNews().getId());
        jo.put("title", newsInfo.getNews().getTitle());
        jo.put("content", newsInfo.getNews().getContent());

        return ApiResult.create(jo);
    }

    /**
     * 分页查询新闻列表
     * @param catalogId 类别编号
     * @param page 页码
     * @param size 页面大小
     * @return
     */
    @GetMapping("/list/catalog/{id}")
    public ApiResult getListOfPage(@PathVariable(name = "id") String catalogId,
                                   @RequestParam(defaultValue = "1", required = false) int page,
                                   @RequestParam(defaultValue = "10", required = false) int size) {
        // 1、根据栏目获取分页的新闻列表
        Page<NewsInfo> pagedNews = newsService.getPagedNewsOfCatalog(catalogId, page, size, true);
        JSONObject jo = new JSONObject();
        jo.put("total", pagedNews.getTotalElements());
        jo.put("list", convertNewsItems(pagedNews.getContent()));

        // 2、对数据进行格式转换
        return ApiResult.create(jo);
    }

    /**
     * 分页查询新闻列表，包含子节点
     * @param catalogId 节点编号
     * @param page 页码
     * @param size 页面大小
     * @return
     */
    @GetMapping("/all/catalog/id")
    public ApiResult getAllOfPage(@PathVariable(name = "id") String catalogId,
                                  @RequestParam(defaultValue = "1", required = false) int page,
                                  @RequestParam(defaultValue = "10", required = false) int size) {
        // 1、根据栏目获取分页的新闻列表
        Page<NewsInfo> pagedNews = newsService.getPagedNewsOfCatalog(catalogId, page, size, true);
        JSONObject jo = new JSONObject();
        jo.put("total", pagedNews.getTotalElements());
        jo.put("list", convertNewsItems(pagedNews.getContent()));

        // 2、对数据进行格式转换
        return ApiResult.create(jo);
    }

    /**
     * 新闻格式转换
     * @param newsInfo
     * @return
     */
    private JSONObject convertNewsItem(NewsInfo newsInfo) {
        JSONObject jo = new JSONObject();
        jo.put("id", newsInfo.getNews().getId());
        jo.put("title", newsInfo.getNews().getTitle());
        jo.put("author", newsInfo.getNews().getAuthor().getUsername());
        jo.put("updateTime", newsInfo.getNews().getUpdateTime());
        return jo;
    }

    /**
     * 新闻列表格式转换
     * @param newsInfos
     * @return
     */
    private List<JSONObject> convertNewsItems(List<NewsInfo> newsInfos) {
        List<JSONObject> objects = newsInfos.stream().map(newsInfo -> {
            return convertNewsItem(newsInfo);
        }).collect(Collectors.toList());

        return objects;
    }
}
